package com.wiscamp.ninechapters.problems.application.services;

import com.wiscamp.ninechapters.problems.application.assemblers.QuestionTypeAssembler;
import com.wiscamp.ninechapters.problems.application.dto.commands.types.CreateQuestionTypeCommand;
import com.wiscamp.ninechapters.problems.application.dto.commands.types.UpdateQuestionTypeCommand;
import com.wiscamp.ninechapters.problems.application.dto.vo.types.QuestionTypeVO;
import com.wiscamp.ninechapters.problems.domain.repositories.QuestionTypeRepository;
import com.wiscamp.ninechapters.problems.domain.services.QuestionTypeService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class QuestionTypeAppService extends BaseAppService {

    private final QuestionTypeRepository questionTypeRepository;

    private final QuestionTypeService questionTypeService;


    public QuestionTypeAppService(QuestionTypeRepository questionTypeRepository, QuestionTypeService questionTypeService) {
        this.questionTypeRepository = questionTypeRepository;
        this.questionTypeService = questionTypeService;
    }

    // region question type
    @HandleServiceException
    public QuestionTypeVO getQuestionType(@Min(0) long typeId) {
        return AppServiceUtils.getById(typeId, questionTypeService::getQuestionType,
                QuestionTypeAssembler.Instance::toQuestionTypeVO);
    }

    @HandleServiceException
    public QuestionTypeVO getQuestionTypeByCode(@NotBlank String typeCode) {
        return AppServiceUtils.getByText(typeCode, questionTypeRepository::getQuestionTypeByCode,
                QuestionTypeAssembler.Instance::toQuestionTypeVO);
    }

    @HandleServiceException
    public Collection<QuestionTypeVO> getQuestionTypesByName(@NotBlank String typeName) {
        return AppServiceUtils.getListByText(typeName, questionTypeRepository::getQuestionTypesByName,
                QuestionTypeAssembler.Instance::toQuestionTypeVO);
    }

    @HandleServiceException
    public Collection<QuestionTypeVO> getAvailableQuestionTypes() {
        return AppServiceUtils.getList(questionTypeRepository::getAvailableQuestionTypes,
                QuestionTypeAssembler.Instance::toQuestionTypeVO);
    }

    @HandleServiceException
    public QuestionTypeVO createQuestionType(@NotNull CreateQuestionTypeCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), questionTypeService::createQuestionType,
                QuestionTypeAssembler.Instance::toQuestionTypeVO, QuestionTypeAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public QuestionTypeVO updateQuestionType(@NotNull UpdateQuestionTypeCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), questionTypeService::updateQuestionType,
                QuestionTypeAssembler.Instance::toQuestionTypeVO, QuestionTypeAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deleteQuestionType(@NotNull DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), questionTypeService::deleteQuestionType);
    }

    @HandleServiceException
    public boolean enableQuestionType(@NotNull EnableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), questionTypeService::enableQuestionType);
    }

    @HandleServiceException
    public boolean disableQuestionType(@NotNull DisableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), questionTypeService::disableQuestionType);
    }
    // endregion

}
